package com.ydj.framework.interceptor;

import com.ydj.framework.annotation.AllowGuest;
import com.ydj.framework.exception.VerifyTokenException;
import com.ydj.framework.filter.ExtHttpServletRequest;
import com.ydj.framework.filter.ExtHttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Slf4j
public abstract class AuthBaseInterceptor extends BaseInterceptor {
	public abstract boolean doPreHandle(ExtHttpServletRequest request, ExtHttpServletResponse response, Object handler, String requestToken) throws VerifyTokenException;

	public abstract String getPathPatterns();

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (!(request instanceof ExtHttpServletRequest) || !(response instanceof ExtHttpServletResponse)) {
			return false;
		}

		// 检测是否允许非登录状态访问
		ExtHttpServletRequest extHttpServletRequest = (ExtHttpServletRequest) request;
		ExtHttpServletResponse extHttpServletResponse = (ExtHttpServletResponse) response;
		String token = extHttpServletRequest.getToken();
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();

		// 有Token的情况, 就需要去检查的了
		if (StringUtils.isNotBlank(token)) {
			try {
				return doPreHandle(extHttpServletRequest, extHttpServletResponse, handler, token);
			} catch (VerifyTokenException e) {
				if (method.getAnnotation(AllowGuest.class) == null) {
					// 不允许匿名访问, 直接报错了
					throw e;
				}
				return true;
			}
		} else {
			// 没有token的情况
			if (method.getAnnotation(AllowGuest.class) != null) {
				// 允许匿名访问，直接放行
				return true;
			} else {
				// 不允许匿名访问, 直接报错了
				throw new VerifyTokenException();
			}
		}
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
	}
}